<template>
  <div>
    <el-form label-position="left" class="flow-config-attr" label-width="90px">
      <el-divider>新增事件</el-divider>
      <el-form-item label="触发时机">
        <el-select
          v-model="form.methods"
          class="input-attr"
          multiple
          clearable
          placeholder="多个方法名称, 英文逗号分隔, 顺序从左到右"
        >
          <el-option
            v-for="item in data.flowMethods"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="事件处理器">
        <CommonSelect
          v-model:defaultValue="form.listenerId"
          placeholder="请选择事件处理器"
          autoQuery
          label="listenerName"
          value="id"
          url="/esflow/def/event/listener/getlist"
          @change="handleListenerChange"
          :width="300"
        />
      </el-form-item>
      <el-form-item label="参数">
        <el-button type="primary" icon="circle-plus" @click="addOption">添加参数</el-button>
        <div
          style="display: flex; justify-content: space-between"
          v-for="(option, i) in form.eventParams"
          :key="option.key"
        >
          <el-input v-model="form.eventParams[i].key" />
          <el-input v-model="form.eventParams[i].value" />
          <el-button icon="Delete" @click="form.eventParams.splice(i, 1)" />
        </div>
      </el-form-item>
      <div style="margin: 10px 13px">
        <span style="font-size: 14px; color: red"
          >注: 事件允许设置生效条件，用于控制在某种条件下才会执行</span
        >
      </div>
      <el-form-item label="条件模式">
        <el-radio-group
          v-model="form.conditionType"
          style="width: 313px"
          :disabled="!validateNull(_value.props.listeners)"
          @change="methods.handleChangeconditionType"
        >
          <el-radio
            v-for="(item, index) in DIC_PROP.VAL_TYPE.slice(0, 3)"
            :key="index"
            :value="item.value"
            :label="item.label"
          />
        </el-radio-group>
        <el-tooltip placement="top">
          <template #content>若无法切换模式，请先清空事件列表</template>
          <el-icon><QuestionFilled /></el-icon>
        </el-tooltip>
      </el-form-item>
      <el-form-item v-if="form.conditionType === '1'" label="SpEL表达式">
        <el-input
          v-model="condComplex.varKeyVal"
          class="input-attr"
          clearable
          @blur="methods.validateVarKeyVal"
        />
        <el-tooltip placement="top">
          <template #content>{{ PROP_CONST.TEXT_DESC.condSpELExplain }}</template>
          <el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
        </el-tooltip>
      </el-form-item>

      <el-form-item v-if="form.conditionType === '2'" label="函数表达式">
        <el-input
          v-model="condComplex.varKeyVal"
          class="input-attr"
          clearable
          @blur="methods.validateVarKeyVal"
        />
        <el-tooltip placement="top">
          <template #content>
            {{ PROP_CONST.TEXT_DESC.condMethodExplain1 }}
            <br />
            {{ PROP_CONST.TEXT_DESC.condMethodExplain2 }}
            <br />
            {{ PROP_CONST.TEXT_DESC.condMethodExplain3 }}
            <br />
            {{ PROP_CONST.TEXT_DESC.condMethodExplain4 }}
          </template>
          <el-icon style="margin-left: 10px"><QuestionFilled /></el-icon>
        </el-tooltip>
      </el-form-item>
      <el-form-item label="监听备注">
        <el-input v-model="form.remark" class="input-attr" type="textarea" />
      </el-form-item>
      <el-form-item label="监听排序">
        <el-input-number v-model="form.sort" class="input-attr" :min="1" />
      </el-form-item>
    </el-form>
    <el-divider v-if="form.conditionType === '0'">组内条件配置</el-divider>
    <div v-if="form.conditionType === '0'">
      <el-form inline-message :model="group">
        <el-form-item label="组内条件关系" label-width="100px" label-position="left">
          <el-switch
            v-model="group.groupItemType"
            active-value="0"
            inactive-value="1"
            inactive-text="或"
            active-text="且"
          />
        </el-form-item>
      </el-form>
      <el-form inline-message :model="group.conditions" ref="conditionFormRef">
        <el-table
          :data="group.conditions"
          border
          style="width: 100%; margin-bottom: 10px"
          max-height="500"
        >
          <el-table-column type="index" label="操作" width="80">
            <template #header>
              <el-button
                icon="Plus"
                size="small"
                type="primary"
                circle
                @click="methods.handleAddSimpleConditionRow()"
              />
            </template>
            <template #default="scope">
              <el-button
                icon="Minus"
                size="small"
                type="danger"
                circle
                @click="methods.handleDeleteSimpleConditionRow(scope.$index)"
              />
            </template>
          </el-table-column>
          <el-table-column prop="varKeyVal" label="表单字段" show-overflow-tooltip>
            <template #default="{ row, column, $index }">
              <el-form-item
                :prop="'[' + $index + '].' + column.property"
                :rules="group.rules.varKeyVal"
              >
                <el-select
                  v-model="row.varKeyVal"
                  clearable
                  filterable
                  @change="methods.handleSimpleItemChange(row)"
                >
                  <el-option
                    v-for="(item, index) in props.formItemList"
                    :key="index"
                    :label="getFormItemLabel(item)"
                    :value="getFormItemKey(item)"
                  />
                </el-select>
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column prop="operator" label="运算符" show-overflow-tooltip>
            <template #default="{ row, column, $index }">
              <el-form-item
                :prop="'[' + $index + '].' + column.property"
                :rules="group.rules.operator"
              >
                <el-select v-model="row.operator" clearable>
                  <el-option
                    v-for="(item, index) in data.varValOperator"
                    :key="index"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </template>
          </el-table-column>

          <el-table-column prop="varVal" label="校验值" show-overflow-tooltip>
            <template #default="{ row, column, $index }">
              <el-form-item
                :prop="'[' + $index + '].' + column.property"
                :rules="group.rules.varVal"
              >
                <el-input v-model="row.varVal" clearable />
              </el-form-item>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
    </div>
    <div style="display: flex; justify-content: center">
      <el-button
        type="primary"
        round
        style="width: 200px; margin-top: 10px; margin-bottom: 10px"
        @click="methods.saveListenerEvent()"
      >
        保存事件
      </el-button>
    </div>
  </div>
</template>
<script setup lang="ts" name="ListenerEvent">
import { useMessage } from "@/hooks/message";
import { validateNull } from "@/utils/validate";
import { DIC_PROP, PROP_CONST } from "../../ProcessDict";
import { getRandNodeId } from "@/utils/process";
import { onMounted, reactive, ref, type PropType } from "vue";
import { getFormItemLabel, getFormItemKey } from "@/views/design/form/FormItem";
import { createNodeListener } from "../../ProcessNodes";
import type { FormItemPerm } from "@/views/design/form/FormTypes";
import type { FlowModelNode } from "../../ProcessDef";

const props = defineProps({
  formItemList: {
    type: Array as PropType<FormItemPerm[]>,
    default: [] as any[]
  }
});

const emits = defineEmits(["confirm"]);

const _value: any = defineModel<FlowModelNode>();

const conditionFormRef = ref(null);

const condComplex = reactive({
  varKeyVal: null
});

const form = reactive({
  listenerId: null,
  listenerName: "",
  methods: "start",
  conditionType: "0",
  remark: "",
  sort: 1,
  eventParams: [],
  groups: []
});

const group = reactive({
  code: getRandNodeId(),
  groupItemType: "0",
  conditions: [],
  rules: {
    varKeyVal: [
      {
        required: true,
        message: "请选择表单字段",
        trigger: "blur"
      }
    ],
    operator: [
      {
        required: true,
        message: "请选择运算符",
        trigger: "blur"
      }
    ],
    varVal: [
      {
        required: true,
        message: "请输入校验值",
        trigger: "blur"
      }
    ]
  }
});

const data = reactive({
  varValOperator: [],
  flowMethods: []
});

onMounted(() => {
  data.varValOperator = DIC_PROP.OPERATOR;
  data.flowMethods = DIC_PROP.NODE_METHODS;
});

const init = (event?: any) => {
  if (event && event.listenerId) {
    form.listenerId = event.listenerId;
    form.listenerName = event.listenerName;
    form.methods = event.methods;
    form.conditionType = event.conditionType;
    form.remark = event.remark;
    form.sort = event.sort;
    if (event.groups && event.groups.length > 0) {
      form.groups = event.groups;
      group.groupItemType = form.groups[0].groupItemType;
      group.conditions = form.groups[0].conditions;
    }
    if (event.eventParams && event.eventParams.length > 0) {
      form.eventParams = event.eventParams;
    }
  }
};

const reset = () => {
  form.listenerId = null;
  form.listenerName = "";
  form.methods = "start";
  form.conditionType = "0";
  form.remark = "";
  form.sort = 1;
  form.groups = [];
  form.eventParams = [];
};

const handleListenerChange = (id, option) => {
  form.listenerName = option.listenerName;
};

function addOption() {
  form.eventParams.push({
    key: "参数名称",
    value: "参数值"
  });
}

const methods = {
  handleSimpleItemChange(row) {
    if (row.varKeyVal && row.varKeyVal.includes(".")) {
      const varKeyValArray = row.varKeyVal.split(".");
      const dots = varKeyValArray.length - 1;
      if (dots === 2) {
        const tableKey = varKeyValArray[1];
        const columnKey = varKeyValArray[2];
        const formItem = props.formItemList.find(
          item => item.tableKey === tableKey && item.columnKey === columnKey
        );
        //默认1：1
        let mainSubRadio = "0";
        console.log(formItem);
        if (!formItem) {
          mainSubRadio = formItem.mainSubRadio;
        }
        //子表映射关系为1:N
        if (mainSubRadio === "1") {
          data.varValOperator = DIC_PROP.OPERATOR.slice(6);
        } else {
          data.varValOperator = DIC_PROP.OPERATOR;
        }
      } else {
        data.varValOperator = DIC_PROP.OPERATOR;
      }
    }
  },
  handleDeleteSimpleConditionRow(index: number) {
    group.conditions.splice(index, 1);
  },
  handleAddSimpleConditionRow() {
    const obj = {
      code: getRandNodeId(),
      varKeyVal: "",
      operator: "",
      varVal: ""
    };
    group.conditions.push(obj);
  },
  saveListenerEvent() {
    if (!form.listenerName) {
      useMessage().warning("请选择事件处理器");
      return;
    }
    if (validateNull(form.methods)) {
      useMessage().warning("触发时机不能为空");
      return;
    }
    if (!validateNull(form.listenerName)) {
      if (!methods.validateClassName()) {
        return;
      }
    }
    if (form.conditionType === "0") {
      conditionFormRef.value.validate().then(valid => {
        if (valid) {
          methods.saveSimpleCondition();
          reset();
          emits("confirm");
        }
      });
    } else {
      methods.saveComplexCondition();
      reset();
      emits("confirm");
    }
  },
  saveSimpleCondition() {
    const listenersList = _value.value.props.listeners.filter(item => {
      return item.conditionType === "0" && item.groups && item.groups.length > 0;
    });
    const event = createNodeListener();
    event.listenerId = form.listenerId;
    event.listenerName = form.listenerName;
    event.methods = form.methods;
    event.conditionType = form.conditionType;
    event.remark = form.remark;
    event.sort = form.sort;
    event.eventParams = form.eventParams;
    event.groups = [
      {
        code: getRandNodeId(),
        groupItemType: group.groupItemType,
        conditions: group.conditions
      }
    ];
    listenersList.push(event);
    form.groups = [];
    _value.value.props.listeners = listenersList;
  },
  saveComplexCondition() {
    const filterRes = _value.value.props.listeners.filter(item => {
      return item.conditionType === form.conditionType;
    });
    if (filterRes && filterRes.length > 0) {
      const groups = _value.value.props.listeners.map(item => {
        if (item.conditionType === form.conditionType) {
          return {
            code: item.code,
            listenerId: form.listenerId,
            listenerName: form.listenerName,
            methods: form.methods,
            conditionType: form.conditionType,
            remark: form.remark,
            sort: form.sort,
            eventParams: form.eventParams,
            groups: [
              {
                code: getRandNodeId(),
                groupItemType: "0",
                conditions: {
                  varKeyVal: condComplex.varKeyVal
                }
              }
            ]
          };
        }
      });
      _value.value.props.listeners = groups;
    } else {
      _value.value.props.listeners = [];
      _value.value.props.listeners.push({
        code: getRandNodeId(),
        listenerId: form.listenerId,
        listenerName: form.listenerName,
        methods: form.methods,
        conditionType: form.conditionType,
        remark: form.remark,
        sort: form.sort,
        eventParams: form.eventParams,
        groups: [
          {
            code: getRandNodeId(),
            groupItemType: "0",
            conditions: {
              varKeyVal: condComplex.varKeyVal
            }
          }
        ]
      });
    }
  },
  validateClassName() {
    const find = _value.value.props.listeners.find(f => f["listenerName"] === form.listenerName);
    if (find) {
      useMessage().warning("请勿重复添加处理器");
      return false;
    }
    return true;
  },
  handleChangeconditionType(type?) {
    if (!type) {
      type = "0";
    }
    form.groups = [];
    form.conditionType = type;
    condComplex.varKeyVal = null;
  },
  validateVarKeyVal() {
    const val = condComplex.varKeyVal;
    if (!val) return;
    const conditionType = form.conditionType;
    if (conditionType === DIC_PROP.VAL_TYPE[1].value && val.indexOf("#") === -1) {
      condComplex.varKeyVal = null;
      useMessage().warning("当选择SpEL模式时, SpEL表达式必须符合SpEL格式");
    } else if (conditionType === DIC_PROP.VAL_TYPE[2].value && val.indexOf("#") === -1) {
      condComplex.varKeyVal = null;
      useMessage().warning("当选择专业模式时, 函数表达式必须符合规定的格式");
    }
  }
};

defineExpose({
  init,
  reset
});
</script>

<style lang="scss" scoped>
@use "@/assets/style/design/flow-attr.scss";
</style>
/@/views/design/form/FormTypes
